'''
@Author: hua
@Date: 2019-12-19 15:44:38
@description: 自动化部署钩子
@LastEditors: hua
@LastEditTime: 2020-02-21 19:37:55
'''
from flask import Flask
from flask import request, make_response
import os, json,time, hmac,hashlib

def getConfig():
    with open(os.getcwd()+'/config.json','rb') as f:
        return json.loads(f.read(), encoding="")

def handleError(e):
    print(e)
    with open('error.txt','a+') as f:
        f.write(str(e))
        
class WebHook:
    
    ''' 服务器器监听IP '''
    _ip:str

    ''' 服务器监听端口 '''
    _port:int

    def __init__(self, ip:str,port:int):
        self._ip = ip
        self._port = port

    def run(self):
        app = Flask(__name__)
        app.debug = True
        @app.route('/gitee', methods=['POST'])
        def giteeTask():
            try:
                self.onTask('Gitee', request.get_json())
            except Exception as e:
                handleError(e)
                raise e
            return make_response('<p>Author: huashiyuting (<a href="https://gitee.com/huashiyuting" target="_blank">Gitee</a></p>')

        @app.route('/github', methods=['POST'])
        def githubTask():
            try:
                self.onTask('Github', request.get_json())
            except Exception as e:
                handleError(e)
                raise e
            return make_response('<p>Author: huashiyuting (<a href="https://gitee.com/huashiyuting" target="_blank">Gitee</a></p>')
        if __name__ == '__main__':
            app.run(host=self._ip, port=self._port)
        return app
        
    def parseGitee(self, data):
        ''' 
        * 处理码云
        *
        * @param array data
        * @return void
        '''
        config = getConfig()
        for item in config['sites']['gitee']:
            if 'name' in item and item['name'] != data['project']['path_with_namespace']:
                handleError("name error")
                continue
            if 'password' in item and item['password'] != data['password']:
                handleError("password error")
                continue
            if "hook_name" in item and item['hook_name'] != data['hook_name']:
                handleError("hook_name error")
                continue
            if "ref" in item and item['ref'] != data['ref']:
                handleError("ref error")
                continue
            if 'cmds' not in item or not isinstance(item['cmds'], list):
                handleError("cmds error")
                break;
            for cmd in item['cmds']:
                os.system(cmd)
            handleError(time.strftime('%Y-%m-%d %H:%M:%S')+":"+item['name']+'gitee hook\n')
            return;
        handleError('gitee no action\n')

    def parseGithub(self, data):
        ''' 
        * 处理Github
        *
        * @param dict data
        * @return void
        '''
        config = getConfig()
        for item in config['sites']['github']:
            if 'name' in item and item['name'] != data['repository']['full_name']:
                handleError("name error")
                continue
            if 'password' in item:
                algo, hash = data['header']['x-hub-signature'].split("=")     
                myHash = hmac.new(item['password'], data, hashlib.sha256).hexdigest()
                if hash != myHash:
                    handleError("password error")
                    continue
            if "hook_name" in item and item['hook_name'] != data['header']['x-github-event']:
                handleError("hook_name error")
                continue
            if "ref" in item and item['ref'] != data['ref']:
                handleError("ref error")
                continue
            if 'cmds' not in item or isinstance(item['cmds'], list):
                handleError("cmds error")
                break;
            for cmd in item['cmds']:
                os.system(cmd)
            handleError('github hook\n');
            return;

    def onTask(self, name, task):
        print(task)
        if name:
            if name == 'Gitee':
                self.parseGitee(task)
                return
            if name == 'Github':
                self.parseGithub(task)
                return


config = getConfig()
host = config['server']['host']
port = config['server']['port']
webhook = WebHook(host, port) 
app = webhook.run()
del config